<html><head><title>org.jdesktop.animation.timing.triggers.MouseTrigger</title></head><body><div id='tit'>org.jdesktop.animation.timing.triggers.MouseTrigger</div><div id='cate'>源码品读</div><div id='date'>2010年06月22日 星期二 02:29 P.M.</div><div id='page'>13</div><a id='url' href='http://hi.baidu.com/hxzon/blog/item/407eb51c8cc6e08686d6b61b.html'>http://hi.baidu.com/hxzon/blog/item/407eb51c8cc6e08686d6b61b.html</a><div id='cnt'><p>org.jdesktop.animation.timing.triggers.MouseTrigger</p> 
<p>Timing Framework 触发器</p> 
<p>-----------------------------------------------------</p> 
<p>工厂方法：</p> 
<pre>MouseTrigger.addTrigger(triggerButton, overAnimator, MouseTriggerEvent.ENTER);</pre> 
<p>鼠标触发器，实现鼠标监听器接口</p> 
<pre>public class MouseTrigger extends Trigger implements MouseListener</pre> 
<p>注册到组件的事件监听器</p> 
<pre>public static MouseTrigger addTrigger(JComponent component,<br />            Animator animator, MouseTriggerEvent event, boolean autoReverse) {<br />        MouseTrigger trigger = new MouseTrigger(animator, event, autoReverse);<br />        component.addMouseListener(trigger);<br />        return trigger;<br />    }</pre> 
<p>实现监听器接口，触发事件</p> 
<pre>public void mousePressed(MouseEvent e) {<br />        fire(MouseTriggerEvent.PRESS);<br />    }</pre> 
<p>触发器父类Trigger</p> 
<pre>/**<br />     * Called by subclasses to start the animator if currentEvent equals<br />     * the event that the Trigger is based upon.  Also, if the Trigger is<br />     * set to autoReverse, stops and reverses the animator running in the<br />     * opposite direction as appropriate.<br />     * @param currentEvent the {@link TriggerEvent} that just occurred, which<br />     * will be compared with the TriggerEvent used to construct this Trigger<br />     * and determine whether the animator should be started or reversed<br />     */<br />    protected void fire(TriggerEvent currentEvent) {<br />        if (disarmed) {<br />            return;<br />        }<br />        if (currentEvent == triggerEvent) {<br />            // event occurred; fire the animation<br />            if (autoReverse) {<br />                if (animator.isRunning()) {<br />                    float f = animator.getTimingFraction();<br />                    animator.stop();<br />                    animator.setStartFraction(f);<br />                } else {<br />                    animator.setStartFraction(0f);<br />                }<br />            }<br />            if (animator.isRunning()) {<br />                animator.stop();<br />            }<br />            animator.setStartDirection(Animator.Direction.FORWARD);<br />            fire();<br />        } else if (triggerEvent != null &amp;&amp; <br />                currentEvent == triggerEvent.getOppositeEvent()) {<br />            // Opposite event occurred - run reverse anim if autoReverse<br />            if (autoReverse) {<br />                if (animator.isRunning()) {<br />                    float f = animator.getTimingFraction();<br />                    animator.stop();<br />                    animator.setStartFraction(f);<br />                } else {<br />                    animator.setStartFraction(1f - <br />                            animator.getStartFraction());<br />                }<br />                animator.setStartDirection(Animator.Direction.BACKWARD);<br />                fire();<br />            }<br />        }<br />    }<br />    <br />    /**<br />     * Utility method called by subclasses to start the animator.  This variant<br />     * assumes that there need be no check of the TriggerEvent that fired,<br />     * which is useful for subclasses with simple events.<br />     */<br />    protected void fire() {<br />        if (disarmed) {<br />            return;<br />        }<br />        if (animator.isRunning()) {<br />            animator.stop();<br />        }<br />        animator.start();<br />    }</pre> 
<p>---------------------------------------------------------------</p> 
<p>org.jdesktop.animation.timing.triggers.MouseTrigger</p> 
<pre>/**<br /> * Copyright (c) 2007, Sun Microsystems, Inc<br /> * All rights reserved.<br /> * <br /> * Redistribution and use in source and binary forms, with or without<br /> * modification, are permitted provided that the following conditions<br /> * are met:<br /> * <br /> *   * Redistributions of source code must retain the above copyright<br /> *     notice, this list of conditions and the following disclaimer.<br /> *   * Redistributions in binary form must reproduce the above<br /> *     copyright notice, this list of conditions and the following <br /> *     disclaimer in the documentation and/or other materials provided <br /> *     with the distribution.<br /> *   * Neither the name of the TimingFramework project nor the names of its<br /> *     contributors may be used to endorse or promote products derived <br /> *     from this software without specific prior written permission.<br /> * <br /> * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS<br /> * &quot;AS IS&quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT<br /> * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR<br /> * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT<br /> * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,<br /> * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT<br /> * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,<br /> * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY<br /> * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT<br /> * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE<br /> * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.<br /> */<br /><br />package org.jdesktop.animation.timing.triggers;<br /><br />import java.awt.event.MouseEvent;<br />import java.awt.event.MouseListener;<br />import javax.swing.JComponent;<br />import org.jdesktop.animation.timing.Animator;<br /><br />/**<br /> * MouseTrigger handles mouse events<br /> * and triggers an animation based on those events.<br /> * For example, to have anim start when component receives an<br /> * ENTER event, one might write the following:<br /> * &lt;pre&gt;<br /> *     MouseTrigger trigger = <br /> *         MouseTrigger.addTrigger(component, anim, MouseTriggerEvent.ENTER);<br /> * &lt;/pre&gt;<br /> * <br /> * <br /> * <br /> * @author Chet<br /> */<br />public class MouseTrigger extends Trigger implements MouseListener {<br />    <br />    /**<br />     * Creates a non-auto-reversing MouseTrigger and adds it as a <br />     * listener to component.<br />     * <br />     * @param component component that will generate MouseEvents for this<br />     * trigger<br />     * @param animator the Animator that will start when the event occurs<br />     * @param event the MouseTriggerEvent that will cause the action to fire<br />     * @return MouseTrigger the resulting trigger<br />     */<br />    public static MouseTrigger addTrigger(JComponent component,<br />            Animator animator, MouseTriggerEvent event) {<br />        return addTrigger(component, animator, event, false);<br />    }<br />    <br />    /**<br />     * Creates a MouseTrigger and adds it as a listener to component.<br />     * <br />     * @param component component that will generate MouseEvents for this<br />     * trigger<br />     * @param animator the Animator that will start when the event occurs<br />     * @param event the FocusTriggerEvent that will cause the action to fire<br />     * @param autoReverse flag to determine whether the animator should<br />     * stop and reverse based on opposite triggerEvents.<br />     * @return FocusTrigger the resulting trigger<br />     */<br />    public static MouseTrigger addTrigger(JComponent component,<br />            Animator animator, MouseTriggerEvent event, boolean autoReverse) {<br />        MouseTrigger trigger = new MouseTrigger(animator, event, autoReverse);<br />        component.addMouseListener(trigger);<br />        return trigger;<br />    }<br />    <br />    /**<br />     * Creates a non-auto-reversing MouseTrigger, which should be added<br />     * to a Component that will generate the mouse events of interest<br />     */<br />    public MouseTrigger(Animator animator, MouseTriggerEvent event) {<br />        this(animator, event, false);<br />    }<br /><br />    /**<br />     * Creates a MouseTrigger, which should be added<br />     * to a Component that will generate the mouse events of interest<br />     */<br />    public MouseTrigger(Animator animator,<br />            MouseTriggerEvent event, boolean autoReverse) {<br />        super(animator, event, autoReverse);<br />    }<br /><br />    /**<br />     * Called by the object which added this trigger as a MouseListener.<br />     * This method starts the animator if the trigger is waiting for an<br />     * ENTER event.<br />     */<br />    public void mouseEntered(MouseEvent e) {<br />        fire(MouseTriggerEvent.ENTER);<br />    }<br /><br />    /**<br />     * Called by the object which added this trigger as a MouseListener.<br />     * This method starts the animator if the trigger is waiting for an<br />     * EXIT event.<br />     */<br />    public void mouseExited(MouseEvent e) {<br />        fire(MouseTriggerEvent.EXIT);<br />    }<br /><br />    /**<br />     * Called by the object which added this trigger as a MouseListener.<br />     * This method starts the animator if the trigger is waiting for a<br />     * PRESS event.<br />     */<br />    public void mousePressed(MouseEvent e) {<br />        fire(MouseTriggerEvent.PRESS);<br />    }<br /><br />    /**<br />     * Called by the object which added this trigger as a MouseListener.<br />     * This method starts the animator if the trigger is waiting for a<br />     * RELEASE event.<br />     */<br />    public void mouseReleased(MouseEvent e) {<br />        fire(MouseTriggerEvent.RELEASE);<br />    }<br /><br />    /**<br />     * Called by the object which added this trigger as a MouseListener.<br />     * This method starts the animator if the trigger is waiting for a<br />     * CLICK event.<br />     */<br />    public void mouseClicked(MouseEvent e) {<br />        fire(MouseTriggerEvent.CLICK);<br />    }<br />    <br />}</pre> 
<p>----------------------------------------------------------------</p> 
<p>org.jdesktop.animation.timing.triggers.Trigger</p> 
<pre>/**<br /> * Copyright (c) 2006, Sun Microsystems, Inc<br /> * All rights reserved.<br /> * <br /> * Redistribution and use in source and binary forms, with or without<br /> * modification, are permitted provided that the following conditions<br /> * are met:<br /> * <br /> *   * Redistributions of source code must retain the above copyright<br /> *     notice, this list of conditions and the following disclaimer.<br /> *   * Redistributions in binary form must reproduce the above<br /> *     copyright notice, this list of conditions and the following <br /> *     disclaimer in the documentation and/or other materials provided <br /> *     with the distribution.<br /> *   * Neither the name of the TimingFramework project nor the names of its<br /> *     contributors may be used to endorse or promote products derived <br /> *     from this software without specific prior written permission.<br /> * <br /> * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS<br /> * &quot;AS IS&quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT<br /> * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR<br /> * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT<br /> * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,<br /> * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT<br /> * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,<br /> * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY<br /> * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT<br /> * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE<br /> * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.<br /> */<br /><br />package org.jdesktop.animation.timing.triggers;<br /><br />import org.jdesktop.animation.timing.Animator;<br /><br />/**<br /> * This abstract class should be overridden by any class wanting to<br /> * implement a new Trigger.  The subclass will define the events to trigger<br /> * off of and any listeners to handle those events. That subclass will call<br /> * either {@link #fire()} or {@link #fire(TriggerEvent)} to start the<br /> * animator based on an event that occurred.<br /> * &lt;p&gt;<br /> * Subclasses should call one of the constructors in Trigger, according to<br /> * whether they want Trigger to discern between different TriggerEvents<br /> * and whether they want Trigger to auto-reverse the animation based on<br /> * opposite TriggerEvents.  <br /> * &lt;p&gt;<br /> * Subclasses should call one of the &lt;code&gt;fire&lt;/code&gt; methods based on<br /> * whether they want Trigger to perform any event logic or simply start<br /> * the animation.<br /> *<br /> * @author Chet<br /> */<br />public abstract class Trigger {<br /><br />    private boolean disarmed = false;<br />    private Animator animator, reverseAnimator;<br />    private TriggerEvent triggerEvent;<br />    private boolean autoReverse = false;<br /><br />    /**<br />     * Creates a Trigger that will start the animator when {@link #fire()}<br />     * is called. Subclasses call this method to set up a simple Trigger<br />     * that will be started by calling {@link #fire()}, and will have<br />     * no dependency upon the specific {@link TriggerEvent} that must have<br />     * occurred to start the animator.<br />     * @param animator the Animator that will start when the Trigger<br />     * is fired<br />     */<br />    protected Trigger(Animator animator) {<br />        this(animator, null);<br />    }<br />    <br />    /**<br />     * Creates a Trigger that will start the animator when <br />     * {@link #fire(TriggerEvent)} is called with an event that equals<br />     * triggerEvent.<br />     * @param animator the Animator that will start when the Trigger<br />     * is fired<br />     * @param triggerEvent the TriggerEvent that must occur for this<br />     * Trigger to fire<br />     */<br />    protected Trigger(Animator animator, TriggerEvent triggerEvent) {<br />        this(animator, triggerEvent, false);<br />    }<br />    <br />    /**<br />     * Creates a Trigger that will start the animator when <br />     * {@link #fire(TriggerEvent)} is called with an event that equals<br />     * triggerEvent. Also, automatically stops and reverses animator when <br />     * opposite event occurs, and stops reversing animator likewise<br />     * when triggerEvent occurs.<br />     * @param animator the Animator that will start when the Trigger<br />     * is fired<br />     * @param triggerEvent the TriggerEvent that must occur for this<br />     * Trigger to fire<br />     * @param autoReverse flag to determine whether the animator should<br />     * stop and reverse based on opposite triggerEvents.<br />     * @see TriggerEvent#getOppositeEvent()<br />     */<br />    protected Trigger(Animator animator, TriggerEvent triggerEvent,<br />            boolean autoReverse) {<br />        this.animator = animator;<br />        this.triggerEvent = triggerEvent;<br />        this.autoReverse = autoReverse;<br />    }<br />    <br />    /**<br />     * This method disables this Trigger and effectively noop's any actions<br />     * that would otherwise occur<br />     */<br />    public void disarm() {<br />        disarmed = true;<br />    }<br /><br />    /**<br />     * Called by subclasses to start the animator if currentEvent equals<br />     * the event that the Trigger is based upon.  Also, if the Trigger is<br />     * set to autoReverse, stops and reverses the animator running in the<br />     * opposite direction as appropriate.<br />     * @param currentEvent the {@link TriggerEvent} that just occurred, which<br />     * will be compared with the TriggerEvent used to construct this Trigger<br />     * and determine whether the animator should be started or reversed<br />     */<br />    protected void fire(TriggerEvent currentEvent) {<br />        if (disarmed) {<br />            return;<br />        }<br />        if (currentEvent == triggerEvent) {<br />            // event occurred; fire the animation<br />            if (autoReverse) {<br />                if (animator.isRunning()) {<br />                    float f = animator.getTimingFraction();<br />                    animator.stop();<br />                    animator.setStartFraction(f);<br />                } else {<br />                    animator.setStartFraction(0f);<br />                }<br />            }<br />            if (animator.isRunning()) {<br />                animator.stop();<br />            }<br />            animator.setStartDirection(Animator.Direction.FORWARD);<br />            fire();<br />        } else if (triggerEvent != null &amp;&amp; <br />                currentEvent == triggerEvent.getOppositeEvent()) {<br />            // Opposite event occurred - run reverse anim if autoReverse<br />            if (autoReverse) {<br />                if (animator.isRunning()) {<br />                    float f = animator.getTimingFraction();<br />                    animator.stop();<br />                    animator.setStartFraction(f);<br />                } else {<br />                    animator.setStartFraction(1f - <br />                            animator.getStartFraction());<br />                }<br />                animator.setStartDirection(Animator.Direction.BACKWARD);<br />                fire();<br />            }<br />        }<br />    }<br />    <br />    /**<br />     * Utility method called by subclasses to start the animator.  This variant<br />     * assumes that there need be no check of the TriggerEvent that fired,<br />     * which is useful for subclasses with simple events.<br />     */<br />    protected void fire() {<br />        if (disarmed) {<br />            return;<br />        }<br />        if (animator.isRunning()) {<br />            animator.stop();<br />        }<br />        animator.start();<br />    }<br />    <br />}</pre> 
<p> </p> 
<p> </p> 
<p> </p></div></body></html>